using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using SevenWizards1.CoreComponents;

namespace SevenWizards1
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        StartScreen startScreen;
        NewGameScreen newGameScreen;
        HelpScreen helpScreen;
        ActionScreen actionScreen;

        PopUpScreen quitPopUpScreen;
        PopUpScreen genderPopUpScreen;
        PopUpScreen classPopUpScreen;
        PopUpScreen difficultyPopUpScreen;
        PopUpScreen namePopUpScreen;

        GameScreen activeScreen;

        SpriteFont normalFont;

        Texture2D background;

        KeyboardState newState;
        KeyboardState oldState;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            graphics.PreferredBackBufferWidth = 1024;
            graphics.PreferredBackBufferHeight = 768;
            graphics.IsFullScreen = false;
            this.Window.Title = "The Seven Wizards of the Crimson Mists";
            Content.RootDirectory = "Content";
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            Services.AddService(typeof(SpriteBatch), spriteBatch);
            Services.AddService(typeof(ContentManager), Content);

            normalFont = Content.Load<SpriteFont>("normal");
            newGameScreen = new NewGameScreen(this, normalFont);
            Components.Add(newGameScreen);

            background = Content.Load<Texture2D>("TitleScreen");
            startScreen = new StartScreen(this,
                normalFont,
                background,
                Content.Load<Texture2D>(@"GUI\buttonbackground"));
            Components.Add(startScreen);

            background = Content.Load<Texture2D>("Pentagrammo");
            helpScreen = new HelpScreen(this,
                normalFont,
                background,
                Content.Load<Texture2D>(@"GUI\buttonbackground"));
            Components.Add(helpScreen);

            actionScreen = new ActionScreen(this, normalFont, "tileset1");
            Components.Add(actionScreen);
            actionScreen.Hide();

            background = Content.Load<Texture2D>(@"GUI\quitpopupbackground");
            quitPopUpScreen = new PopUpScreen(this,
                normalFont,
                background,
                Content.Load<Texture2D>(@"GUI\buttonbackgroundshort"));
            Components.Add(quitPopUpScreen);
            quitPopUpScreen.Hide();

            background = Content.Load<Texture2D>(@"GUI\maleorfemale");

            genderPopUpScreen = new PopUpScreen(this,
                normalFont,
                background,
                Content.Load<Texture2D>(@"GUI\buttonbackgroundshort"));
            string[] genderItems = new string[] { "Female", "Male" };
            genderPopUpScreen.SetMenuItems(genderItems);
            Components.Add(genderPopUpScreen);
            
            background = Content.Load<Texture2D>(@"GUI\chooseclass");
            
            classPopUpScreen = new PopUpScreen(this,
                normalFont,
                background,
                Content.Load<Texture2D>(@"GUI\buttonbackgroundshort"));
            string[] classItems = new string[] { "Fighter",
                "Wizard",
                "Thief",
                "Priest" };

            classPopUpScreen.SetMenuItems(classItems);
            Components.Add(classPopUpScreen);

            background = Content.Load<Texture2D>(@"GUI\choosedifficulty");

            difficultyPopUpScreen = new PopUpScreen(this,
                normalFont,
                background,
                Content.Load<Texture2D>(@"GUI\buttonbackgroundshort"));
            
            string[] difficultyItems = new string[] { "Easy",
                "Normal",
                "Hard",
                "Ultimate" };

            difficultyPopUpScreen.SetMenuItems(difficultyItems);
            Components.Add(difficultyPopUpScreen);

            background = Content.Load<Texture2D>(@"GUI\choosename");
            
            namePopUpScreen = new PopUpScreen(this,
                normalFont,
                background,
                Content.Load<Texture2D>(@"GUI\buttonbackgroundshort"));
            namePopUpScreen.SetMenuItems(NewGameScreen.MaleNames);
            Components.Add(namePopUpScreen);

            startScreen.Show();
            helpScreen.Hide();
            newGameScreen.Hide();

            activeScreen = startScreen;
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            newState = Keyboard.GetState();

            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            if (newState.IsKeyDown(Keys.Escape))
                this.Exit();

            if (activeScreen == startScreen)
            {
                HandleStartScreenInput();
            }
            else if (activeScreen == helpScreen)
            {
                HandleHelpScreenInput();
            }
            else if (activeScreen == newGameScreen)
            {
                HandleNewGameScreenInput();
            }
            else if (activeScreen == quitPopUpScreen)
            {
                HandleQuitPopUpScreenInput();
            }
            else if (activeScreen == genderPopUpScreen)
            {
                HandleGenderPopUpScreenInput();
            }
            else if (activeScreen == classPopUpScreen)
            {
                HandleClassPopUpScreenInput();
            }
            else if (activeScreen == difficultyPopUpScreen)
            {
                HandleDifficultyPopUpScreenInput();
            }
            else if (activeScreen == namePopUpScreen)
            {
                HandleNamePopUpScreenInput();
            }
            oldState = newState;

            base.Update(gameTime);
        }

        private void HandleNamePopUpScreenInput()
        {
            if (CheckKey(Keys.Enter) || CheckKey(Keys.Space))
            {
                newGameScreen.ChangeName(namePopUpScreen.SelectedIndex);
                activeScreen.Hide();
                activeScreen = newGameScreen;
                activeScreen.Show();
            }
        }
        private void HandleDifficultyPopUpScreenInput()
        {
            if (CheckKey(Keys.Enter) || CheckKey(Keys.Space))
            {
                newGameScreen.ChangeDifficulty(difficultyPopUpScreen.SelectedIndex);
                activeScreen.Hide();
                activeScreen = newGameScreen;
                activeScreen.Show();
            }
        }
        private void HandleClassPopUpScreenInput()
        {
            if (CheckKey(Keys.Enter) || CheckKey(Keys.Space))
            {
                newGameScreen.ChangeClass(classPopUpScreen.SelectedIndex);
                activeScreen.Hide();
                activeScreen = newGameScreen;
                activeScreen.Show();
            }
        }
        private void HandleGenderPopUpScreenInput()
        {
            if (CheckKey(Keys.Enter) || CheckKey(Keys.Space))
            {
                switch (genderPopUpScreen.SelectedIndex)
                {
                    case 0:
                        newGameScreen.ChangeGender(true);
                        activeScreen.Hide();
                        activeScreen = newGameScreen;
                        activeScreen.Show();
                        break;
                    case 1:
                        newGameScreen.ChangeGender(false);
                        activeScreen.Hide();
                        activeScreen = newGameScreen;
                        activeScreen.Show();
                        break;
                }
            }
        }

        private void HandleHelpScreenInput()
        {
            if (CheckKey(Keys.Space) || CheckKey(Keys.Enter) || CheckKey(Keys.Escape))
            {
                switch (helpScreen.SelectedIndex)
                {
                    case 0:
                        activeScreen.Hide();
                        activeScreen = startScreen;
                        activeScreen.Show();
                        break;
                }
            }
        }

        private void HandleStartScreenInput()
        {
            if (CheckKey(Keys.Enter) || CheckKey(Keys.Space))
            {
                switch (startScreen.SelectedIndex)
                {
                    case 0:
                        //CONTINUE SAVED GAME
                        activeScreen.Hide();
                        activeScreen = actionScreen;
                        activeScreen.Show();
                        break;
                    case 1:
                        //NEW GAME
                        activeScreen.Hide();
                        activeScreen = newGameScreen;
                        activeScreen.Show();
                        break;
                    case 2:
                        //EXIT
                        activeScreen.Enabled = false;
                        activeScreen = quitPopUpScreen;
                        activeScreen.Show();
                        break;
                }
            }
        }

        private void HandleNewGameScreenInput()
        {
            if (CheckKey(Keys.Enter) || CheckKey(Keys.Space))
            {
                switch (newGameScreen.SelectedIndex)
                {
                    case 0:
                        activeScreen.Enabled = false;
                        if (newGameScreen.Gender)
                            namePopUpScreen.SetMenuItems(NewGameScreen.FemaleNames);
                        else
                            namePopUpScreen.SetMenuItems(NewGameScreen.MaleNames);
                        activeScreen = namePopUpScreen;
                        activeScreen.Show();
                        break;
                    case 1:
                        activeScreen.Enabled = false;
                        activeScreen = genderPopUpScreen;
                        activeScreen.Show();
                        break;
                    case 2:
                        activeScreen.Enabled = false;
                        activeScreen = classPopUpScreen;
                        activeScreen.Show();
                        break;
                    case 3:
                        activeScreen.Enabled = false;
                        activeScreen = difficultyPopUpScreen;
                        activeScreen.Show();
                        break;
                    case 4:
                        activeScreen.Hide();
                        activeScreen = startScreen;
                        activeScreen.Show();
                        break;
                    case 5:
                        activeScreen.Hide();
                        activeScreen = actionScreen;
                        activeScreen.Show();
                        break;
                }
            }
        }

        private void HandleQuitPopUpScreenInput()
        {
            if (CheckKey(Keys.Enter) || CheckKey(Keys.Space))
            {
                switch (quitPopUpScreen.SelectedIndex)
                {
                    case 0:
                        this.Exit();
                        break;
                    case 1:
                        activeScreen.Hide();
                        activeScreen = startScreen;
                        activeScreen.Show();
                        break;
                }
            }
        }

        private bool CheckKey(Keys theKey)
        {
            return oldState.IsKeyDown(theKey) && newState.IsKeyUp(theKey);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
            base.Draw(gameTime);
            spriteBatch.End();
        }
    }
}
